home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-21 | 13.4 KB | 460 lines | [TEXT/MPS ] |
- // ===========================================================================
- //
- // GSRandomTriMesh.c
- //
- // Copyright (C) 1996 Apple Computer, Inc. All rights reserved.
- //
- // ===========================================================================
-
-
- // ===========================================================================
- // Includes
- // ===========================================================================
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #include "RAVE.h"
-
- #include "GSRandomTriMesh.h"
- #include "GSImage.h"
- #include "GSPicture.h"
- #include "GSColorTable.h"
- #include "GSDrawInfo.h"
- #include "GSUtilities.h"
- #include "GSError.h"
-
-
- // ===========================================================================
- // Constants
- // ===========================================================================
-
- #define kGSTriangleCount 100
- #define kGSTexturePath "GS_RedLava.16.pict"
-
-
- // ===========================================================================
- // Private Prototypes
- // ===========================================================================
-
- TGSError
- GSLoadTextureFromPath(
- TGSDrawInfo* inDrawInfo,
- char* inPath,
- TGSImage** outImage,
- TQAColorTable** outColorTable,
- TQATexture** outTexture);
-
- void
- GSRandomVGouraud(
- TGSDrawInfo* inDrawInfo,
- TQAVGouraud* v);
-
- void
- GSRandomVTexture(
- TGSDrawInfo* inDrawInfo,
- TQAVTexture* v);
-
-
- // ===========================================================================
- // GSRandomTriMeshGouraud
- // ===========================================================================
- TGSError
- GSRandomTriMeshGouraud(
- TGSDrawInfo* inDrawInfo)
- {
- TQAIndexedTriangle* triangles = nil;
- TQAVGouraud* vertices = nil;
- TGSError status = kGSError_None;
- long vertexCount = 2 * kGSTriangleCount;
- long i;
-
- // reset the random seed to 1. if it's the same value every time
- // this function is called, it'll be easier to debug.
- srand(1);
-
- // allocate 2 vertices for every triangle we want to draw.
- // this means that on average every triangle will be connected to at
- // least one other.
- vertices = malloc(vertexCount * sizeof(TQAVTexture));
-
- if (vertices == nil) {
- status = kGSError_NotEnoughMemory;
- goto cleanup;
- }
-
- // allocate a single TQAIndexedTriangle for every triangle we
- // wants draw. these will hold the indexes into the vertices.
- triangles = malloc(kGSTriangleCount * sizeof(TQAIndexedTriangle));
-
- if (triangles == nil) {
- status = kGSError_NotEnoughMemory;
- goto cleanup;
- }
-
- // fill in the array of vertices with random values. we have to fill
- // in the uOverW and vOverW values before calling RandomVTexture because
- // that function assumes they've already been set.
- for (i = 0; i < vertexCount; i++) {
- GSRandomVGouraud(inDrawInfo, &vertices[i]);
- } // endfor
-
- // fill in the default tri flags for each triangle, and calculate a
- // random index for each of the three vertex indexes.
- for (i = 0; i < kGSTriangleCount; i++) {
- triangles[i].triangleFlags = kQATriFlags_None;
-
- triangles[i].vertices[0] =
- (long) (GSRandomFloat() * (vertexCount - 1));
- triangles[i].vertices[1] =
- (long) (GSRandomFloat() * (vertexCount - 1));
- triangles[i].vertices[2] =
- (long) (GSRandomFloat() * (vertexCount - 1));
- } // endfor
-
- QARenderStart(inDrawInfo->mContext, nil, nil);
-
- QASubmitVerticesGouraud(inDrawInfo->mContext, vertexCount, vertices);
-
- QADrawTriMeshGouraud(inDrawInfo->mContext, kGSTriangleCount, triangles);
-
- QARenderEnd(inDrawInfo->mContext, nil);
-
- QASync(inDrawInfo->mContext);
-
- cleanup:
- if (vertices != nil) {
- free(vertices);
- }
-
- if (triangles != nil) {
- free(triangles);
- }
-
- return status;
- }
-
-
- // ===========================================================================
- // GSRandomTriMeshTexture
- // ===========================================================================
- TGSError
- GSRandomTriMeshTexture(
- TGSDrawInfo* inDrawInfo)
- {
- TQAIndexedTriangle* triangles = nil;
- TQAVTexture* vertices = nil;
- TQATexture* texture = nil;
- TQAColorTable* colorTable = nil;
- TGSImage* image = nil;
- TGSError gsError = kGSError_None;
- TGSError status = kGSError_None;
- long vertexCount = 2 * kGSTriangleCount;
- long i;
-
- // reset the random seed to 1. if it's the same value every time
- // this function is called, it'll be easier to debug.
- srand(1);
-
- // load the texture from a file
- gsError = GSLoadTextureFromPath(inDrawInfo, kGSTexturePath, &image,
- &colorTable, &texture);
-
- if (gsError != kGSError_None) {
- status = gsError;
- goto cleanup;
- }
-
- // set the current texture for this context to be the one we just loaded
- QASetPtr(inDrawInfo->mContext, kQATag_Texture, texture);
-
- // allocate 2 vertices for every triangle we want to draw.
- // this means that on average every triangle will be connected to at
- // least one other.
- vertices = malloc(vertexCount * sizeof(TQAVTexture));
-
- if (vertices == nil) {
- status = kGSError_NotEnoughMemory;
- goto cleanup;
- }
-
- // allocate a single TQAIndexedTriangle for every triangle we
- // wants draw. these will hold the indexes into the vertices.
- triangles = malloc(kGSTriangleCount * sizeof(TQAIndexedTriangle));
-
- if (triangles == nil) {
- status = kGSError_NotEnoughMemory;
- goto cleanup;
- }
-
- // fill in the array of vertices with random values. we have to fill
- // in the uOverW and vOverW values before calling RandomVTexture because
- // that function assumes they've already been set.
- for (i = 0; i < vertexCount; i++) {
- vertices[i].uOverW = GSRandomFloat();
- vertices[i].vOverW = GSRandomFloat();
-
- GSRandomVTexture(inDrawInfo, &vertices[i]);
- } // endfor
-
- // fill in the default tri flags for each triangle, and calculate a
- // random index for each of the three vertex indexes.
- for (i = 0; i < kGSTriangleCount; i++) {
- triangles[i].triangleFlags = kQATriFlags_None;
-
- triangles[i].vertices[0] =
- (long) (GSRandomFloat() * (vertexCount - 1));
- triangles[i].vertices[1] =
- (long) (GSRandomFloat() * (vertexCount - 1));
- triangles[i].vertices[2] =
- (long) (GSRandomFloat() * (vertexCount - 1));
- } // endfor
-
- QARenderStart(inDrawInfo->mContext, nil, nil);
-
- QASubmitVerticesTexture(inDrawInfo->mContext, vertexCount, vertices);
-
- QADrawTriMeshTexture(inDrawInfo->mContext, kGSTriangleCount, triangles);
-
- QARenderEnd(inDrawInfo->mContext, nil);
-
- QASync(inDrawInfo->mContext);
-
- cleanup:
- if (vertices != nil) {
- free(vertices);
- }
-
- if (triangles != nil) {
- free(triangles);
- }
-
- if (image != nil) {
- GSImage_Delete(image);
- }
-
- if (texture != nil) {
- QATextureDelete(inDrawInfo->mEngine, texture);
- }
-
- if (colorTable != nil) {
- QAColorTableDelete(inDrawInfo->mEngine, colorTable);
- }
-
- return status;
- }
-
-
- // ===========================================================================
- // GSLoadTextureFromPath
- // ===========================================================================
- TGSError
- GSLoadTextureFromPath(
- TGSDrawInfo* inDrawInfo,
- char* inPath,
- TGSImage** outImage,
- TQAColorTable** outColorTable,
- TQATexture** outTexture)
- {
- TGSPicture* picture = nil;
- TQAError qaError = kQANoErr;
- TGSError gsError = kGSError_None;
- TGSError status = kGSError_None;
-
- // set the pointers the caller passed to us to nil so we can tell
- // if these objects were actually created or not
- *outImage = nil;
- *outColorTable = nil;
- *outTexture = nil;
-
- // read the picture data from the file pointed to by the path into a
- // TGSPicture. this object handles any necessary conversion from
- // the format of the picture data in the file to the RAVE texture
- // format. the disposal of this picture will be handled by the
- // TGSImage we create below.
- gsError = GSPicture_NewFromPath(&picture, inDrawInfo->mTextureFormat,
- inPath);
-
- if (gsError != kGSError_None) {
- // we couldn't find the picture file, so return the error. we don't
- // have to delete the GSPicture, because it deletes itself if an
- // error occurs in the New call.
- status = gsError;
- goto failure;
- }
-
- // create a TGSImage from the TGSPicture we just created above.
- // this object fills in the TQAImage structure with the appropriate
- // values from the TGSPicture. it will also optionally make every
- // black pixel in the picture transparent and create mip maps for
- // the texture. it handles the disposal of the TGSPicture. we use
- // the TGSImage below to create an actual RAVE texture.
- gsError = GSImage_NewFromPicture(outImage, picture,
- inDrawInfo->mTextureFormat, inDrawInfo->mTextureMakeBlackTransparent,
- inDrawInfo->mTextureMakeMipMap);
-
- if (gsError != kGSError_None) {
- // for some reason we couldn't create a GSImage (probably not
- // enough memory), so return the error. GSImage also deletes when
- // an error occurs in the New call.
- status = gsError;
- goto failure;
- }
-
- if (inDrawInfo->mTextureMakeMipMap && !GSImage_IsValidMipMap(*outImage)) {
- // the texture is supposed to be mipmapped, but GSImage couldn't
- // mip map it for some reason
- status = kGSError_RAVE;
- goto failure;
- }
-
- // try to create a texture for the engine, using the image data in
- // our TGSImage object. we'll return the texture to the caller in
- // outTexture.
- qaError = QATextureNew(inDrawInfo->mEngine, inDrawInfo->mTextureFlags,
- GSImage_GetPixelType(*outImage),
- GSImage_GetImages(*outImage),
- outTexture);
-
- if (qaError != kQANoErr) {
- // for some reason the engine couldn't create a texture (probably
- // not enough memory), so return a RAVE error
- status = kGSError_RAVE;
- goto failure;
- }
-
- if (inDrawInfo->mTextureFormat == kQAPixel_CL4 ||
- inDrawInfo->mTextureFormat == kQAPixel_CL8) {
- TGSColorTable* colorTableP = GSImage_GetColorTable(*outImage);
- GSAssert_(colorTableP);
-
- // create a new color table in the engine from the color table
- // data in the TGSImage. when a TGSPicture is created, it also
- // creates a TGSColorTable, if necessary, which in turn stores
- // the color table from the picture file in an array of pixels
- // in TQAImagePixelType format. we can get the TGSColorTable
- // out of the TGSImage by calling GSImage_GetColorTable.
- //
- // once the color table data has been used to create a
- // TQAColorTable, we can delete it. in this case, however, it
- // won't be deleted until the TGSPicture which stores it is
- // itself deleted.
- qaError = QAColorTableNew(inDrawInfo->mEngine,
- GSColorTable_GetType(colorTableP),
- GSColorTable_GetData(colorTableP),
- inDrawInfo->mTextureUseTransparentIndex,
- outColorTable);
-
- if (qaError != kQANoErr) {
- // we couldn't create a color table in this engine (perhaps
- // it doesn't support CL textures), so break out of the loop,
- // since we can't continue if the engine can't create
- // color tables.
- status = kGSError_RAVE;
- goto failure;
- }
-
- // bind this color table to the texture.
- qaError = QATextureBindColorTable(inDrawInfo->mEngine,
- *outTexture, *outColorTable);
-
- if (qaError != kQANoErr) {
- // we couldn't bind this color table to the texture in
- // this engine, so break out of the loop, since we won't
- // be able to draw this texture
- status = kGSError_RAVE;
- goto failure;
- }
- }
-
- if (inDrawInfo->mTextureDetach) {
- // try to detach the texture from the engine
- qaError = QATextureDetach(inDrawInfo->mEngine, *outTexture);
-
- // if the texture was successfully detached, delete the image
- // which stores the texture's pixmap, since the engine now
- // has its own copy of that data. if the texture couldn't be
- // detached, don't do anything (i.e., hold on to the image).
- if (qaError == kQANoErr) {
- GSImage_Delete(*outImage);
- *outImage = nil;
- }
- }
-
- return status;
-
- failure:
- if (*outImage != nil) {
- // this will also delete picture
- GSImage_Delete(*outImage);
- *outImage = nil;
- } else if (picture != nil) {
- // the image was never created, so we have to delete the picture
- // manually
- GSPicture_Delete(picture);
- }
-
- if (*outTexture != nil) {
- QATextureDelete(inDrawInfo->mEngine, *outTexture);
- *outTexture = nil;
- }
-
- if (*outColorTable != nil) {
- QAColorTableDelete(inDrawInfo->mEngine, *outColorTable);
- *outTexture = nil;
- }
-
- return status;
- }
-
-
- // ===========================================================================
- // GSRandomVGouraud
- // ===========================================================================
- void
- GSRandomVGouraud(
- TGSDrawInfo* inDrawInfo,
- TQAVGouraud* v)
- {
- v->x = GSRandomFloat() * (float) (inDrawInfo->mContextRect.right - inDrawInfo->mContextRect.left) - 0.1;
- v->y = GSRandomFloat() * (float) (inDrawInfo->mContextRect.bottom - inDrawInfo->mContextRect.top) - 0.1;
- v->z = GSRandomFloat();
- v->invW = 1.0 / v->z;
-
- v->a = 1.0;
- v->r = GSRandomFloat();
- v->g = GSRandomFloat();
- v->b = GSRandomFloat();
- }
-
-
- // ===========================================================================
- // GSRandomVTexture
- // ===========================================================================
- void
- GSRandomVTexture(
- TGSDrawInfo* inDrawInfo,
- TQAVTexture* v)
- {
- v->x = GSRandomFloat() * (float) (inDrawInfo->mContextRect.right - inDrawInfo->mContextRect.left) - 0.1;
- v->y = GSRandomFloat() * (float) (inDrawInfo->mContextRect.bottom - inDrawInfo->mContextRect.top) - 0.1;
- v->z = GSRandomFloat();
- v->invW = 1.0 / v->z;
-
- v->uOverW *= v->invW;
- v->vOverW *= v->invW;
-
- v->a = 1.0;
- v->r = GSRandomFloat();
- v->g = GSRandomFloat();
- v->b = GSRandomFloat();
-
- v->kd_r = 1.0;
- v->kd_g = 1.0;
- v->kd_b = 1.0;
-
- v->ks_r = 0.0;
- v->ks_g = 0.0;
- v->ks_b = 0.0;
- }
-